package edu.deltacollege.portal.portlets.emailpreview;

import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * Selects an {@link EmailMessageDAO} for a given {@link AccountInfoDAO}
 * using an injected map and a fallback default. The mapping
 * must succeed, else will raise an unchecked exception.
 */
public class SimpleEmailMessageDAOSelector implements EmailMessageDAOSelector {

    private Map<String,EmailMessageDAO> daos;
    private EmailMessageDAO defaultDao;

    private Log log;

    public SimpleEmailMessageDAOSelector () {
        this.log = LogFactory.getLog(SimpleEmailMessageDAOSelector.class);
    }
    
    public EmailMessageDAO getEmailMessageDAO(AccountInfoDAO accountInfoDAO) {
        if ( daos == null || daos.isEmpty() ) {
            if ( this.log.isDebugEnabled() ) {
                this.log.debug("No configured EmailMessageDAOs, falling back to default DAO if possible.");
            }
            return getDefaultEmailMessageDAOOrFail(accountInfoDAO);
        }
        String preferredDaoName = accountInfoDAO.getPreferredEmailMessageDAOName();
        if ( preferredDaoName == null || !(daos.containsKey(preferredDaoName)) ) {
            if ( this.log.isDebugEnabled() ) {
                this.log.debug("Preferred EmailMessageDAO name [" + preferredDaoName + "] does not resolve. Valid names: [" + 
                        daos.keySet() + "]. falling back to default DAO if possible.");
            }
            return getDefaultEmailMessageDAOOrFail(accountInfoDAO);
        }
        EmailMessageDAO dao = daos.get(preferredDaoName);
        if ( !(dao.supports(accountInfoDAO)) ) {
            if ( this.log.isDebugEnabled() ) {
                this.log.debug("Preferred EmailMessageDAO of name [" + preferredDaoName + "] does not support the current AccountInfoDAO configuration. Falling back to default DAO if possible.");
            }
            return getDefaultEmailMessageDAOOrFail(accountInfoDAO);
        }
        return dao;
    }
    
    protected EmailMessageDAO getDefaultEmailMessageDAOOrFail(
            AccountInfoDAO accountInfoDAO) {
        EmailMessageDAO dao = getDefaultEmailMessageDAO(accountInfoDAO);
        if ( dao == null ) {
            throw new IllegalStateException("Unable to produce a default EmailMessageDAO for the current AccountInfoDAO.");
        }
        return dao;
    }
    
    protected EmailMessageDAO getDefaultEmailMessageDAO(
            AccountInfoDAO accountInfoDAO) {
        if ( defaultDao == null ) {
            return null;
        }
        if ( !(defaultDao.supports(accountInfoDAO)) ) {
            return null;
        }
        return defaultDao;
    }

    public Map<String, EmailMessageDAO> getDaos() {
        return daos;
    }

    public void setDaos(Map<String, EmailMessageDAO> daos) {
        this.daos = daos;
    }

    public EmailMessageDAO getDefaultDao() {
        return defaultDao;
    }

    public void setDefaultDao(EmailMessageDAO defaultDao) {
        this.defaultDao = defaultDao;
    }
    
}
